package com.pdwl.cashoutpay.timer;


import com.pdwl.cashoutpay.dao.TradeMapper;
import com.pdwl.cashoutpay.entity.Merchant;
import com.pdwl.cashoutpay.entity.Trade;
import com.pdwl.cashoutpay.entity.res.BaseEntity;
import com.pdwl.cashoutpay.entity.res.TradeRes;
import com.pdwl.cashoutpay.service.MerchantRegisterService;
import com.pdwl.cashoutpay.service.OrderService;
import com.pdwl.cashoutpay.util.ContanGobal;
import com.pdwl.cashoutpay.util.HttpUtil;
import com.pdwl.cashoutpay.util.LogUtils;
import com.pdwl.cashoutpay.util.TimeUtil;
import net.sf.json.JSONObject;
import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.DigestException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("timerQueryServerImp")
@EnableAsync
@EnableScheduling
public class TimerQueryServerImp {
    @Autowired
    TradeMapper tradeMapper;

    @Value("${queryOrderUrl}")
    private String queryOrderUrl;

    @Value("${tradeRate}")
    private String tradeRate;

    @Value("${remitFee}")
    private String remitFee;

    @Autowired
    private OrderService orderService;

    @Autowired
    private MerchantRegisterService merchantRegisterService;


    /**
     * 查询,定时查询只有查询时间频率不一样,调用同一个方法 每天凌晨2点查询所有状态不明订单,查询10天内所有状态不明订单
     *
     * @throws JSONException
     * @throws DigestException
     * @throws UnsupportedEncodingException
     */
    @Scheduled(cron = "00 00 02 * * ?")
    public void tenSendQuery() throws Exception {
        String endTime = TimeUtil.getTime("yyyyMMddHHmmss");
        // 查询14400分钟内的所用订单
        String startTime = TimeUtil.timeShift2(endTime, -14400, "MINUTE");
        List<Trade> listTrade = tradeMapper.getTradebytime(startTime, endTime);
        for (int i = 0; i < listTrade.size(); i++) {
            Trade tr = listTrade.get(i);
            // 调用通用查询服务
            try {
                comQuery(tr);
            } catch (Exception e) {
                LogUtils.logError(String.valueOf(e));
            }
        }
    }


    //线程1,需要查询订单总数
    int tradeNum1;
    //线程1,已经查询的次数
    int queryNum1;

    /**
     * 线程1 ,消费查询服务(5分钟内,3秒钟查询一次)
     *
     * @throws JSONException
     * @throws DigestException
     * @throws UnsupportedEncodingException
     */
    @Scheduled(fixedRate = 3000)
    public void tradeQuery1() throws Exception {
        String time = TimeUtil.getTime("HHmmss");
        // 如何意外导致订单没有查询完毕而导致查询中断,每天2点左右进行重置
        if ((time.compareTo("020005") > 0) && (time.compareTo("020014") < 0)) {
            tradeNum1 = queryNum1;
        }
        if (tradeNum1 == queryNum1) {
            String endTime = TimeUtil.getTime("yyyyMMddHHmmss");
            // 查询5分钟之内的所用订单
            String startTime = TimeUtil.timeShift2(endTime, -5, "MINUTE");
            List<Trade> listTrade = tradeMapper.getTradebytime(startTime, endTime);
            // 需要查询订单总数
            tradeNum1 = listTrade.size();
            // 已经查询订单的次数
            queryNum1 = 0;
            for (int i = 0; i < listTrade.size(); i++) {
                Trade tr = listTrade.get(i);
                // 调用通用查询服务
                try {
                    comQuery(tr);
                } catch (Exception e) {
                    LogUtils.logError(String.valueOf(e));
                }
                queryNum1++;
                LogUtils.logInfo(TimeUtil.getTime("yyyyMMddHHmmss") + "查询次数为:" + queryNum1);
            }
        }
    }


    public void comQuery(Trade trade) throws JSONException {
        Map payReq = new HashMap<String, String>();
        payReq.put("orderNo", trade.getOurorderid()); //商户订单号
        payReq.put("merchantCode", ContanGobal.OURMERCHANTCODE); //接入商编号
        payReq.put("subMerchantCode", trade.getSubmerchcode()); //莱付商户号

        String res = HttpUtil.formUpload(queryOrderUrl, payReq);

        LogUtils.logInfo("订单查询，上游得到的信息：" + res);

        org.json.JSONObject jsonRes = new org.json.JSONObject(res);
        String flag = (String) jsonRes.getString("flag");
        if ("true".equals(flag)) {
            String data = jsonRes.getString("data");
            JSONObject message = JSONObject.fromObject(data);
            String orderStatus = message.getString("orderStatus");
            if ("Y".equals(orderStatus)) {
                LogUtils.logInfo("查询订单状态成功，出款成功，订单号为：" + trade.getOurorderid());
                trade.setStatus("1");
                String channelOrderNo = message.getString("channelOrderNo");
                trade.setToporderid(channelOrderNo);
                trade.setMessage("出款成功");

                trade = getTraderate(trade);

                TradeRes tradeRes = new TradeRes();
                tradeRes.setOrderid(trade.getOrderid());
                tradeRes.setOurorderid(trade.getOurorderid());
                tradeRes.setAmount(trade.getAmount());
                tradeRes.setNotifyurl(trade.getNotifyurl());
                tradeRes.setCriditno(trade.getCriditno());
                tradeRes.setBankphoneno(trade.getBankphoneno());
                tradeRes.setStatus(trade.getStatus());
                tradeRes.setMessage(trade.getMessage());

                BaseEntity baseEntity = new BaseEntity();
                baseEntity.setError_code("1");
                baseEntity.setError_message("出款成功");
                baseEntity.setData(tradeRes);

                String notifyUrl = trade.getNotifyurl();
                JSONObject json = JSONObject.fromObject(baseEntity);//将java对象转换为json对象
                LogUtils.logInfo("查询订单状态成功,发送到商户的信息:" + json.toString());
                HttpUtil.httpRequest(notifyUrl, "POST", json.toString());

            }
            if ("C".equals(orderStatus)) {
                LogUtils.logInfo("查询订单状态，交易关闭，订单号为：" + trade.getOurorderid());
                trade.setStatus("2");
                String channelOrderNo = message.getString("channelOrderNo");
                trade.setToporderid(channelOrderNo);
                trade.setMessage("交易关闭");
                orderService.update(trade);
            }
            if ("N".equals(orderStatus)) {
                LogUtils.logInfo("查询订单状态，出款失败，订单号为：" + trade.getOurorderid());
                trade.setStatus("00");
                String channelOrderNo = message.getString("channelOrderNo");
                trade.setToporderid(channelOrderNo);
                trade.setMessage("出款失败");
                orderService.update(trade);
            }
            if ("F".equals(orderStatus)) {
                LogUtils.logInfo("查询订单状态，交易失败，订单号为：" + trade.getOurorderid());
                trade.setStatus("2");
                String channelOrderNo = message.getString("channelOrderNo");
                trade.setToporderid(channelOrderNo);
                trade.setMessage("交易失败");
                orderService.update(trade);
            }
            if ("W".equals(orderStatus)) {
                LogUtils.logInfo("查询订单状态，等待支付，订单号为：" + trade.getOurorderid());
                String channelOrderNo = message.getString("channelOrderNo");
                trade.setToporderid(channelOrderNo);
                trade.setMessage("等待支付");
                orderService.update(trade);
            }
            if ("S".equals(orderStatus)) {
                LogUtils.logInfo("查询订单状态，交易成功，订单号为：" + trade.getOurorderid());
                String channelOrderNo = message.getString("channelOrderNo");
                trade.setToporderid(channelOrderNo);
                trade.setMessage("交易成功");
                orderService.update(trade);
            }
        }
    }

    public Trade getTraderate(Trade trade) {
        LogUtils.logInfo("开始计算费率,单号为:" + trade.getOurorderid());
        Merchant merchant = merchantRegisterService.queryBySubMerchCode(trade.getSubmerchcode());
        Merchant agent = merchantRegisterService.queryByOutMerchCode(merchant.getPMercId());

        BigDecimal money = new BigDecimal(trade.getAmount());
        BigDecimal first = new BigDecimal(tradeRate);
        BigDecimal sub = new BigDecimal(agent.getTraderate());
        BigDecimal third = new BigDecimal(merchant.getTraderate());

        BigDecimal one = new BigDecimal(remitFee);
        BigDecimal two = new BigDecimal(agent.getRemitfee());
        BigDecimal three = new BigDecimal(merchant.getRemitfee());

        trade.setTraderate(money.multiply(first).add(one).setScale(2, BigDecimal.ROUND_HALF_DOWN) + "");
        trade.setSubtraderate(money.multiply(sub).add(two).setScale(2, BigDecimal.ROUND_HALF_DOWN) + "");
        trade.setThirdtraderate(money.multiply(third).add(three).setScale(2, BigDecimal.ROUND_HALF_DOWN) + "");
        orderService.update(trade);
        return trade;
    }

}
